#include "OclLapack.h"
#include "../clUtils.h"
#include "clAmdBlas.h"
#include "../ClMem.h"
#include "../AmdConvertEnum.h"

inline bool isTranspose(const char* trans) {	
    return (tolower(trans[0]) != 'n');
}

void OclLapack::sgemm(const char* transA, const char* transB, int m, int n, int k, float alpha,
		const cl_ptr a, int lda,
		const cl_ptr b, int ldb,
		float beta,
		cl_ptr c, int ldc) 
{
	Measure measure("sgemm-ocl");
	
	cl_event event;
	CL_CHECK(clAmdBlasSgemmEx(clAmdBlasColumnMajor,
			toAmdTrans(transA), toAmdTrans(transB),
			m, n, k, alpha,
			a.handle, a.offset, lda,
			b.handle, b.offset, ldb,
			beta,
			c.handle, c.offset, ldc,
			1, &queue, 0, NULL, &event));
	ClEvent(event).wait();
}

int OclLapack::sgemm(char *transa, char *transb, int *m, int *
	n, int *k, float *alpha, float *a, int *lda, float *b, int *
	ldb, float *beta, float *c, int *ldc) 
{
	size_t ka = isTranspose(transa) ? *m : *k;
	ClMem<float> memA(queue, (*lda) * ka, a);	
	size_t kb = isTranspose(transb) ? *k : *n;
	ClMem<float> memB(queue, (*ldb) * kb, b);
	size_t sizeC = (*ldc) * (*n);
	ClMem<float> memC(queue, sizeC, c);
    
	sgemm(transa, transb, *m, *n, *k, *alpha,
		cl_ptr(memA), *lda,
        cl_ptr(memB), *ldb, 
		*beta,
        cl_ptr(memC), *ldc);	

	memC.beginRead(c, 0, sizeC).wait();
	
    return 0;
}
